package com.photoeditor.demo.ui.widget.beauty;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.common.base.ComponentContext;
import com.common.base.utils.DeviceUtils;
import com.photoeditor.R;
import com.photoeditor.demo.util.FontUtil;
import com.photoeditor.demo.util.ImageRectUtils;


/**
 * 增高的View
 * 可以设置上下可增高范围, 默认相等
 */

public class TailImageView extends View {

    private final int SELECT_AREA_SIZE = DeviceUtils.dip2px(ComponentContext.getContext(), 20);

    //增高上面的距离
    private float mTailPaddingTop = DeviceUtils.dip2px(ComponentContext.getContext(), 32);

    //增高底部的距离
    private float mTailPaddingBottom = DeviceUtils.dip2px(ComponentContext.getContext(), 32);

    private final static float LINE_HEIGHT = DeviceUtils.dip2px(ComponentContext.getContext(), 2f);

    //按钮距离右边的距离
    private final static float RIGHT_DISTANCE = DeviceUtils.dip2px(ComponentContext.getContext(), 6f);

    private Paint mBgPaint;
    private Paint mLinePaint;
    private TextPaint mTextPaint;

    private boolean mIsInit;
    private RectF mRect;//相对于View

    private RectF mImageRect;//相对于View  这个是图片容器的Rect

    private Rect mBaseDrawableRect;//cacheBitmap的Rect

    //原图
    private Bitmap mSrcBitmap;

    //缓存当前的图片
    private Bitmap mCacheBitmap;

    //当前显示的Matrix
    private Matrix mMatrix;
    private float mScale = 1.0f;

    //用于缓存的Rect
    private RectF mAreaCacheRect;
    private RectF mTopCacheRect;
    private RectF mBottomCacheRect;
    private Rect mBitmapCacheRect;
    private RectF mDrawCacheRect;

    //两条直线
    private RectF mDrawableRect;//这个是图片真正展示出来的Rect 不会拉伸的
    private float mFirstY;//这个也是拉伸后不会变的
    private float mSecondY;//这个也是拉伸后不会变的

    //下面三个和上面的一致  只是拉伸的时候下面的会改变, 但是上面的是在保存后才会发生改变
    private float mChangeFirstY;//这个也是拉伸后会变的
    private float mChangeSecondY;//这个也是拉伸后会变的
    private RectF mChangeDrawableRect;//这个也是拉伸后会变的

    //中间的文字
    private String mTip;
    private StaticLayout mTipLayout;
    private float mTipMaxWidth;


    //处理事件
    private int mTouchMode = MODE_NONE;
    private final static int MODE_NONE = 0;
    private final static int MODE_FIRST_LINE = 1;
    private final static int MODE_SECOND_LINE = 2;

    private boolean mShowTips = true;

    //扩大的进度
    private float mAddHeight = 0;
    private final static int MAX_TAIL_HEIGHT = DeviceUtils.dip2px(ComponentContext.getContext(), 24f);

    //当前最小的图片高度
    private final static int MIN_HEIGHT = DeviceUtils.dip2px(ComponentContext.getContext(), 60f);

    //两条线能缩小的最小大小
    private final static int MIN_LINE_HEIGHT = DeviceUtils.dip2px(ComponentContext.getContext(), 2f);

    private IProgressListener mProgressListener;

    //操作Drawable
    private Drawable mOperationDrawable;
    private Drawable mOperationClickDrawable;


    private boolean mShowOriginalBitmap;//是否展示原始图片

    private boolean mIsMin;

    public TailImageView(Context context) {
        this(context, null);
    }

    public TailImageView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TailImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        onCreate();
    }

    private void onCreate() {
        setWillNotDraw(false);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBgPaint.setColor(Color.parseColor("#332599ff"));

        mLinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mLinePaint.setColor(Color.parseColor("#7fffffff"));

        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.WHITE);
        mTextPaint.setTextSize(DeviceUtils.dip2px(ComponentContext.getContext(), 16));
        mTextPaint.setTypeface(FontUtil.CUSTOM_FONT);
        mIsInit = false;

        mRect = new RectF();
        mImageRect = new RectF();
        mDrawableRect = new RectF();
        mBaseDrawableRect = new Rect();
        mChangeDrawableRect = new RectF();

        mMatrix = new Matrix();

        mAreaCacheRect = new RectF();
        mTopCacheRect = new RectF();
        mBottomCacheRect = new RectF();
        mBitmapCacheRect = new Rect();
        mDrawCacheRect = new RectF();
        mTip = getResources().getString(R.string.image_edit_beauty_tail_tips);
        setProgress(50);
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                invalidate();
            }
        });

        mOperationDrawable = getResources().getDrawable(R.drawable.ic_tool_beauty_taller_on);
        mOperationClickDrawable = getResources().getDrawable(R.drawable.ic_tool_beauty_taller_on);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (!mIsInit && mSrcBitmap != null && !mSrcBitmap.isRecycled()) {
            init(ImageRectUtils.getViewRect(this));
        }
    }

    private void init(RectF rectF) {
        if (!mIsInit || !mRect.equals(rectF)) {
            mRect.set(rectF);
            mRect.offset(-mRect.left, -mRect.top);
            mImageRect.set(mRect.left, mRect.top + mTailPaddingTop, mRect.right, mRect.bottom - mTailPaddingBottom);//这个是当前图片放置的位置
            RectF rectCopyOfImageRect = new RectF(mImageRect);
            rectCopyOfImageRect.offset(-mImageRect.left, -mImageRect.top);
            countSupportMatrix(rectCopyOfImageRect, mImageRect.left, mImageRect.top);//计算合适的Matrix
            float allHeight = mDrawableRect.height();
            mFirstY = mDrawableRect.top + allHeight / 4;
            mSecondY = mDrawableRect.bottom - allHeight / 4;
            mChangeFirstY = mFirstY;
            mChangeSecondY = mSecondY;
            float maxWidth = StaticLayout.getDesiredWidth(mTip, mTextPaint);
            //第五个参数用于控制是否换行  如果文字长度超过这个值就会换行
            mTipLayout = new StaticLayout(mTip, 0, mTip.length(), mTextPaint, (int) mDrawableRect.width(),
                    Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false, TextUtils.TruncateAt.END, (int) (maxWidth + 1));
            int count = mTipLayout.getLineCount();
            mTipMaxWidth = mTipLayout.getLineWidth(0);
            for (int i = 1; i < count; i++) {
                float curLineWidth = mTipLayout.getLineWidth(i);
                if (curLineWidth > mTipMaxWidth) {
                    mTipMaxWidth = curLineWidth;
                }
            }
            mIsInit = true;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (!mIsInit) return;
        RectF areaRect = getAreaRect(false);
        RectF topRect = getTopRect(mDrawableRect, areaRect);
        RectF bottomRect = getBottomRect(mDrawableRect, areaRect);
        if (mShowOriginalBitmap) {
            drawOriginalBitmap(canvas);
            return;
        } else {
            drawBitmap(canvas, mBaseDrawableRect, mDrawableRect, topRect, areaRect, bottomRect, mCacheBitmap, mAddHeight, mScale);
        }
        if (isShowTips()) {
            canvas.drawRect(getAreaRect(true), mBgPaint);
            float textW = mTipMaxWidth;//获取第一行的宽度
            float textH = mTipLayout.getHeight();
            float dx = (areaRect.width() - textW) / 2;
            float dy = (areaRect.height() - textH) / 2;
            float left = areaRect.left + dx;
            float top = areaRect.top + dy;
            int saveCount = canvas.save();
            canvas.translate(left, top);
            mTipLayout.draw(canvas);
            canvas.restoreToCount(saveCount);
        }
        if (mChangeFirstY > mChangeSecondY) {//mChangeSecondY 是 top
            canvas.drawRect(mRect.left, mChangeFirstY, mRect.right, mChangeFirstY + LINE_HEIGHT, mLinePaint);
            canvas.drawRect(mRect.left, mChangeSecondY - LINE_HEIGHT, mRect.right, mChangeSecondY, mLinePaint);
            Drawable drawFisrtDrawable = (mTouchMode == MODE_FIRST_LINE) ? mOperationClickDrawable : mOperationDrawable;
            Drawable drawSecondDrawable = (mTouchMode == MODE_SECOND_LINE) ? mOperationClickDrawable : mOperationDrawable;
            int left = Math.round(mRect.right - RIGHT_DISTANCE - drawFisrtDrawable.getIntrinsicWidth());
            int top = Math.round(mChangeFirstY + LINE_HEIGHT / 2 - drawFisrtDrawable.getIntrinsicHeight() / 2);
            drawFisrtDrawable.setBounds(left, top, left + drawFisrtDrawable.getIntrinsicWidth(), top + drawFisrtDrawable.getIntrinsicHeight());
            drawFisrtDrawable.draw(canvas);

            left = Math.round(mRect.right - RIGHT_DISTANCE - drawSecondDrawable.getIntrinsicWidth());
            top = Math.round(mChangeSecondY - LINE_HEIGHT / 2 - drawSecondDrawable.getIntrinsicHeight() / 2);
            drawSecondDrawable.setBounds(left, top, left + drawSecondDrawable.getIntrinsicWidth(), top + drawSecondDrawable.getIntrinsicHeight());
            drawSecondDrawable.draw(canvas);
        } else {//mChangeFirstY 是 top
            canvas.drawRect(mRect.left, mChangeFirstY - LINE_HEIGHT, mRect.right, mChangeFirstY, mLinePaint);
            canvas.drawRect(mRect.left, mChangeSecondY, mRect.right, mChangeSecondY + LINE_HEIGHT, mLinePaint);

            Drawable drawFisrtDrawable = (mTouchMode == MODE_FIRST_LINE) ? mOperationClickDrawable : mOperationDrawable;
            Drawable drawSecondDrawable = (mTouchMode == MODE_SECOND_LINE) ? mOperationClickDrawable : mOperationDrawable;
            int left = Math.round(mRect.right - RIGHT_DISTANCE - drawFisrtDrawable.getIntrinsicWidth());
            int top = Math.round(mChangeFirstY - LINE_HEIGHT / 2 - drawFisrtDrawable.getIntrinsicHeight() / 2);
            drawFisrtDrawable.setBounds(left, top, left + drawFisrtDrawable.getIntrinsicWidth(), top + drawFisrtDrawable.getIntrinsicHeight());
            drawFisrtDrawable.draw(canvas);

            left = Math.round(mRect.right - RIGHT_DISTANCE - drawSecondDrawable.getIntrinsicWidth());
            top = Math.round(mChangeSecondY + LINE_HEIGHT / 2 - drawSecondDrawable.getIntrinsicHeight() / 2);
            drawSecondDrawable.setBounds(left, top, left + drawSecondDrawable.getIntrinsicWidth(), top + drawSecondDrawable.getIntrinsicHeight());
            drawSecondDrawable.draw(canvas);
        }
    }

    /**
     * @param canvas
     * @param baseDrawableRect
     * @param drawableRect     总体的Rect
     * @param topRect
     * @param areaRect
     * @param bottomRect
     * @param bitmap
     * @param addHeight
     * @param scale
     */
    private void drawBitmap(Canvas canvas, Rect baseDrawableRect, RectF drawableRect, RectF topRect, RectF areaRect, RectF bottomRect, Bitmap bitmap, float addHeight, float scale) {
        boolean topHeight0 = (topRect.height() == 0);
        boolean centerHeight0 = (areaRect.height() == 0);
        boolean bottomHeight0 = (bottomRect.height() == 0);
        int width = baseDrawableRect.width();

        //绘制中间部分
        int centerBottom;
        int centerTop;
        float drawCenterTop;
        float drawCenterBottom;
        if (!centerHeight0) {
            centerTop = Math.round((areaRect.top - drawableRect.top) / scale);
            centerBottom = Math.round((areaRect.bottom - drawableRect.top) / scale);
            mBitmapCacheRect.set(0, centerTop, width, centerBottom);
            mDrawCacheRect.set(areaRect.left, drawableRect.top + (centerTop * scale) - (addHeight / 2), areaRect.right, drawableRect.top + (centerBottom * scale) + (addHeight / 2));
            canvas.drawBitmap(bitmap, mBitmapCacheRect, mDrawCacheRect, null);
            drawCenterTop = mDrawCacheRect.top;
            drawCenterBottom = mDrawCacheRect.bottom;
        } else {
            centerTop = Math.round((areaRect.top - drawableRect.top) / scale);
            centerBottom = centerTop;
            drawCenterTop = drawableRect.top + (centerTop * scale);
            drawCenterBottom = drawCenterTop;
        }

        if (!topHeight0) {
            mBitmapCacheRect.set(0, 0, width, centerTop);
            mDrawCacheRect.set(topRect.left, drawableRect.top - (addHeight / 2), topRect.right, drawCenterTop);
            canvas.drawBitmap(bitmap, mBitmapCacheRect, mDrawCacheRect, null);
        }
        if (!bottomHeight0) {
            mBitmapCacheRect.set(0, centerBottom, width, baseDrawableRect.bottom);
            mDrawCacheRect.set(bottomRect.left, drawCenterBottom, bottomRect.right, drawableRect.bottom + (addHeight / 2));
            canvas.drawBitmap(bitmap, mBitmapCacheRect, mDrawCacheRect, null);
        }
    }

    /**
     * @param canvas
     */
    private void drawOriginalBitmap(Canvas canvas) {
        mBitmapCacheRect.set(0, 0, mSrcBitmap.getWidth(), mSrcBitmap.getHeight());
        float maxWidth = mImageRect.width();
        float maxHeight = mImageRect.height();
        float bitmapW = mBitmapCacheRect.width();
        float bitmapH = mBitmapCacheRect.height();
        if (bitmapW / bitmapH > maxWidth / maxHeight) {//图片比较宽, 顶着宽
            float curHeight = maxWidth / bitmapW * bitmapH;
            mDrawCacheRect.set(0, 0, maxWidth, curHeight);
            mDrawCacheRect.offset(mImageRect.left, (maxHeight - curHeight) / 2 + mImageRect.top);
        } else {//顶着高
            float curWidth = maxHeight / bitmapH * bitmapW;
            mDrawCacheRect.set(0, 0, curWidth, maxHeight);
            mDrawCacheRect.offset((maxWidth - curWidth) / 2 + mImageRect.left, mImageRect.top);
        }
        canvas.drawBitmap(mSrcBitmap, mBitmapCacheRect, mDrawCacheRect, null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (!mIsInit) return super.onTouchEvent(event);
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN) {
            if (isSelected(event.getY(), mChangeFirstY)) {
                mTouchMode = MODE_FIRST_LINE;
                setShowTips(true);
                return true;
            } else if (isSelected(event.getY(), mChangeSecondY)) {
                mTouchMode = MODE_SECOND_LINE;
                setShowTips(true);
                return true;
            } else {
                mTouchMode = MODE_NONE;
                setShowTips(false);
            }
        } else if (action == MotionEvent.ACTION_MOVE) {
            if (mTouchMode == MODE_FIRST_LINE) {
                mChangeFirstY = edgeHandle(event.getY(), mChangeDrawableRect.top, mChangeDrawableRect.bottom);
                onLineChange();
                invalidate();
            } else if (mTouchMode == MODE_SECOND_LINE) {
                mChangeSecondY = edgeHandle(event.getY(), mChangeDrawableRect.top, mChangeDrawableRect.bottom);
                onLineChange();
                invalidate();
            }
        } else if (action == MotionEvent.ACTION_UP) {
            if (mTouchMode == MODE_FIRST_LINE || mTouchMode == MODE_SECOND_LINE) {
                onLineChangeEnd();
            }
            mTouchMode = MODE_NONE;
            setShowTips(false);
        } else {
            mTouchMode = MODE_NONE;
            setShowTips(false);
        }
        return super.onTouchEvent(event);
    }

    private boolean isSelected(float y, float centerY) {
        if (centerY - SELECT_AREA_SIZE < y && centerY + SELECT_AREA_SIZE > y)
            return true;
        else
            return false;
    }


    private float edgeHandle(float x, float min, float max) {
        if (x < min)
            return min;
        else if (x > max)
            return max;
        else
            return x;
    }

    /**
     * 获取选中区域的Rect
     *
     * @return
     */
    private RectF getAreaRect(boolean isChange) {//获取不变位置中的区域
        if (isChange) {
            float max = Math.max(mChangeFirstY, mChangeSecondY);
            float min = Math.min(mChangeFirstY, mChangeSecondY);
            mAreaCacheRect.set(mDrawableRect.left, min, mDrawableRect.right, max);
        } else {
            float max = Math.max(mFirstY, mSecondY);
            float min = Math.min(mFirstY, mSecondY);
            mAreaCacheRect.set(mDrawableRect.left, min, mDrawableRect.right, max);
        }
        return mAreaCacheRect;
    }

    /**
     * 获取选中区域上面的部分
     *
     * @param drawableRect
     * @param areaRect
     * @return
     */
    private RectF getTopRect(RectF drawableRect, RectF areaRect) {
        mTopCacheRect.set(drawableRect.left, drawableRect.top, drawableRect.right, areaRect.top);
        return mTopCacheRect;
    }

    /**
     * 获取选中区域下面的部分
     *
     * @param drawableRect
     * @param areaRect
     * @return
     */
    private RectF getBottomRect(RectF drawableRect, RectF areaRect) {
        mBottomCacheRect.set(drawableRect.left, areaRect.bottom, drawableRect.right, drawableRect.bottom);
        return mBottomCacheRect;
    }

    /**
     * 设置图片
     *
     * @param bm
     * @param reset
     */
    public void setImageBitmap(Bitmap bm, boolean reset) {
        if (bm == null) return;
        mSrcBitmap = bm;
        mCacheBitmap = mSrcBitmap;
        mBaseDrawableRect.set(0, 0, bm.getWidth(), bm.getHeight());
        if (reset) {
            mIsInit = false;
        }
    }

    /**
     * 0 - 100
     *
     * @param progress
     * @return 返回值代表可以拉伸的最大值 没有超过就为当前的值
     */
    public int setProgress(int progress) {
        mAddHeight = (progress - 50) / 50f * MAX_TAIL_HEIGHT;
        invalidate();
        if (mDrawableRect.height() + mAddHeight >= mRect.height()) {
            mAddHeight = mRect.height() - mDrawableRect.height();
            lineEdgeHandle();
            mChangeDrawableRect.set(mDrawableRect.left, mDrawableRect.top - (mAddHeight / 2), mDrawableRect.right, mDrawableRect.bottom + (mAddHeight / 2));
            mIsMin = false;
            return (int) (mAddHeight / MAX_TAIL_HEIGHT * 50f + 50 + 0.5f);
        } else if (mDrawableRect.height() + mAddHeight <= MIN_HEIGHT) {
            mAddHeight = MIN_HEIGHT - mDrawableRect.height();
            lineEdgeHandle();
            mChangeDrawableRect.set(mDrawableRect.left, mDrawableRect.top - (mAddHeight / 2), mDrawableRect.right, mDrawableRect.bottom + (mAddHeight / 2));
            mIsMin = true;
            return (int) (mAddHeight / MAX_TAIL_HEIGHT * 50f + 50 + 0.5f);
        } else {
            lineEdgeHandle();
            mChangeDrawableRect.set(mDrawableRect.left, mDrawableRect.top - (mAddHeight / 2), mDrawableRect.right, mDrawableRect.bottom + (mAddHeight / 2));
            return progress;
        }
    }

    public boolean isMin() {
        return mIsMin;
    }

    /**
     * 处理Line相关的
     */
    private void lineEdgeHandle() {
        if (isNotEnough()) {
            mAddHeight = 0;
            mChangeFirstY = mFirstY;
            mChangeSecondY = mSecondY;
        } else {
            if (mChangeFirstY > mChangeSecondY) {
                if (mAddHeight < 0) {
                    mAddHeight = Math.max(Math.min(-(mFirstY - mSecondY - MIN_LINE_HEIGHT), 0), mAddHeight);
                }
                mChangeFirstY = mFirstY + (mAddHeight / 2);
                mChangeSecondY = mSecondY - (mAddHeight / 2);
            } else if (mChangeFirstY < mChangeSecondY) {
                if (mAddHeight < 0) {
                    mAddHeight = Math.max(Math.min(-(mSecondY - mFirstY - MIN_LINE_HEIGHT), 0), mAddHeight);
                }
                mChangeFirstY = mFirstY - (mAddHeight / 2);
                mChangeSecondY = mSecondY + (mAddHeight / 2);
            } else {
                mAddHeight = 0;
                mChangeFirstY = mFirstY;
                mChangeSecondY = mSecondY;
            }
        }
    }

    private boolean isNotEnough() {
        RectF areaRect = getAreaRect(false);
        float centerTop = Math.round((areaRect.top - mDrawableRect.top) / mScale);
        float centerBottom = Math.round((areaRect.bottom - mDrawableRect.top) / mScale);
        if (centerTop == centerBottom) {
            return true;
        }
        return false;
    }

    /**
     * 初始化SupportMatrix
     */
    private void countSupportMatrix(RectF imageRect, float left, float top) {
        mMatrix.reset();
        float bw = mSrcBitmap.getWidth();
        float bh = mSrcBitmap.getHeight();
        RectF baseDrawableRect = new RectF(0, 0, bw, bh);
        mMatrix.setRectToRect(baseDrawableRect, imageRect, Matrix.ScaleToFit.CENTER);//在小区域内部居中
        mMatrix.postTranslate(left, top);
        mMatrix.mapRect(mDrawableRect, new RectF(0, 0, bw, bh));//获取到当前显示的真正的Rect
        mChangeDrawableRect.set(mDrawableRect);
        float[] values = new float[9];
        mMatrix.getValues(values);
        mScale = values[Matrix.MSCALE_X];
    }

    /**
     * 没有拉伸时两个线同步
     */
    private void onLineChange() {
        if (mAddHeight == 0) {//默认状态  同步他们的值
            mFirstY = mChangeFirstY;
            mSecondY = mChangeSecondY;
        }
    }

    /**
     * 再次拉伸时 判断是否需要保存上一次的, 需要就保存并恢复默认的进度值
     */
    private void onLineChangeEnd() {
        saveCurBitmap();
    }

    private void saveCurBitmap() {
        if (!mChangeDrawableRect.equals(mDrawableRect)) {//进行了拉伸, 需要生成一张新的图片重置
            int height = Math.round(mChangeDrawableRect.height() / mScale);
            Bitmap bitmap = Bitmap.createBitmap(mCacheBitmap.getWidth(), height, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);

            RectF areaRect = getAreaRect(false);
            RectF topRect = getTopRect(mDrawableRect, areaRect);
            RectF bottomRect = getBottomRect(mDrawableRect, areaRect);

            boolean topHeight0 = (topRect.height() == 0);
            boolean centerHeight0 = (areaRect.height() == 0);
            boolean bottomHeight0 = (bottomRect.height() == 0);
            int width = mBaseDrawableRect.width();
            float addHeight = mAddHeight / 2 / mScale;
            //绘制中间部分
            int centerBottom;
            int centerTop;
            float drawCenterTop;
            float drawCenterBottom;
            if (!centerHeight0) {
                centerTop = Math.round((areaRect.top - mDrawableRect.top) / mScale);
                centerBottom = Math.round((areaRect.bottom - mDrawableRect.top) / mScale);
                mBitmapCacheRect.set(0, centerTop, width, centerBottom);
                mDrawCacheRect.set(0, centerTop, width, centerBottom + addHeight * 2);
                canvas.drawBitmap(mCacheBitmap, mBitmapCacheRect, mDrawCacheRect, null);
                drawCenterTop = mDrawCacheRect.top;
                drawCenterBottom = mDrawCacheRect.bottom;
            } else {
                centerTop = Math.round((areaRect.top - mDrawableRect.top) / mScale);
                centerBottom = centerTop;
                drawCenterTop = centerTop;
                drawCenterBottom = centerTop;
            }

            if (!topHeight0) {
                mBitmapCacheRect.set(0, 0, width, centerTop);
                mDrawCacheRect.set(0, 0, width, drawCenterTop);
                canvas.drawBitmap(mCacheBitmap, mBitmapCacheRect, mDrawCacheRect, null);
            }
            if (!bottomHeight0) {
                mBitmapCacheRect.set(0, centerBottom, width, mBaseDrawableRect.bottom);
                mDrawCacheRect.set(0, drawCenterBottom, width, height);
                canvas.drawBitmap(mCacheBitmap, mBitmapCacheRect, mDrawCacheRect, null);
            }

            mCacheBitmap = bitmap;
            mBaseDrawableRect.set(0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight());
            mMatrix.postTranslate(0, -(mChangeDrawableRect.height() - mDrawableRect.height()) / 2);
            mMatrix.mapRect(mDrawableRect, new RectF(0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight()));//获取到当前显示的真正的Rect
            mChangeDrawableRect.set(mDrawableRect);
            mFirstY = mChangeFirstY;
            mSecondY = mChangeSecondY;
            setProgress(50);
            if (mProgressListener != null) {
                mProgressListener.onProgress(50);
            }
        } else {//图片没有修改仍然恢复进度条
            setProgress(50);
            if (mProgressListener != null) {
                mProgressListener.onProgress(50);
            }
        }
    }

    public Bitmap getCurBitmap() {
        saveCurBitmap();
        return mCacheBitmap;
    }

    public void reset() {
        mCacheBitmap = mSrcBitmap;
        mBaseDrawableRect.set(0, 0, mCacheBitmap.getWidth(), mCacheBitmap.getHeight());
        RectF rectCopyOfImageRect = new RectF(mImageRect);
        rectCopyOfImageRect.offset(-mImageRect.left, -mImageRect.top);
        countSupportMatrix(rectCopyOfImageRect, mImageRect.left, mImageRect.top);//计算合适的Matrix
        float allHeight = mDrawableRect.height();
        mFirstY = mDrawableRect.top + allHeight / 4;
        mSecondY = mDrawableRect.bottom - allHeight / 4;
        mChangeFirstY = mFirstY;
        mChangeSecondY = mSecondY;
        setProgress(50);
        if (mProgressListener != null) {
            mProgressListener.onProgress(50);
        }
        setShowTips(true);
    }

    public void setProgressListener(IProgressListener mProgressListener) {
        this.mProgressListener = mProgressListener;
    }

    public void showEffect() {
        mShowOriginalBitmap = false;
        invalidate();
    }

    public void showOriginalBitmap() {
        mShowOriginalBitmap = true;
        invalidate();
    }

    public boolean isShowTips() {
        return mShowTips;
    }

    public void setShowTips(boolean showTips) {
        this.mShowTips = showTips;
        invalidate();
    }

    /**
     * 是否改变
     *
     * @return
     */
    public boolean isChanged() {
        if (mAddHeight != 0 || mCacheBitmap != mSrcBitmap) {
            return true;
        }
        return false;
    }

    public interface IProgressListener {
        void onProgress(int progress);
    }
}
